package de.dhbw.karlsruhe.picsim.model.io;

import de.dhbw.karlsruhe.picsim.util.Bits;
import de.dhbw.karlsruhe.picsim.util.impl.BitUtilities;
import de.dhbw.karlsruhe.picsim.util.impl.BitsMutableImpl;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Created by IntelliJ IDEA.
 * User: goesen
 * Date: Apr 18, 2010
 * Time: 11:03:45 AM
 */
public final class ExternalPins implements External {
    private final Collection<ExternalListener> listeners = new CopyOnWriteArraySet<ExternalListener>();
    private final External state;


    public ExternalPins(@NotNull External state) {
        this.state = state;
    }

    @Override
    public void setPortA(@NotNull final Bits value) {
        if (value.getLength() != 5) {
            throw new IllegalArgumentException(value.toString());
        }
        if (!value.equals(state.getPortA())) {
            final Bits oldValue = BitUtilities.clone(state.getPortA());
            state.setPortA(new BitsMutableImpl(value));
            for (final ExternalListener listener : listeners) {
                listener.handlePortAChange(oldValue, getPortA());
            }
        }
    }

    @Override
    public void setPortB(@NotNull final Bits value) {
        if (value.getLength() != 8) {
            throw new IllegalArgumentException(value.toString());
        }

        if (!value.equals(state.getPortB())) {
            final Bits oldValue = BitUtilities.clone(state.getPortB());
            state.setPortB(new BitsMutableImpl(value));
            for (final ExternalListener listener : listeners) {
                listener.handlePortBChange(oldValue, getPortB());
            }
        }
    }

    @NotNull
    @Override
    public Bits getPortA() {
        return BitUtilities.clone(state.getPortA());
    }

    @NotNull
    @Override
    public Bits getPortB() {
        return BitUtilities.clone(state.getPortB());
    }

    @Override
    public void addListener(@NotNull final ExternalListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(@NotNull final ExternalListener listener) {
        listeners.remove(listener);
    }
}
